package com.kele.encryption.util;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAUtil {
    private static final String ALGORITHM = "RSA";

    /**
     * 生成一对RSA公私钥
     * @return 密钥对
     * @throws NoSuchAlgorithmException
     */
    public static KeyPair generateKey() throws NoSuchAlgorithmException {
        // 创建KeyPairGenerator实例
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);
        // 初始化密钥长度，常见的有1024、2048、3072等
        keyPairGen.initialize(2048);
        // 生成密钥对
        return keyPairGen.generateKeyPair();
    }

    /**
     * 加密
     * @param data 待加密的数据
     * @param publicKeyBase64 公钥的Base64编码
     * @return 加密后的数据
     * @throws Exception
     */
    public static String encrypt(String data, String publicKeyBase64) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return encrypt(data, publicKey);
    }

    /**
     * 加密
     * @param data 待加密的数据
     * @param publicKey 公钥
     * @return 加密后的数据
     * @throws Exception
     */
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /**
     * 解密
     * @param data 带解密的数据
     * @param privateKeyBase64 私钥的Base64编码
     * @return 解密后的数据
     * @throws Exception
     */
    public static String decrypt(String data, String privateKeyBase64) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return decrypt(data, privateKey);
    }

    /**
     * 解密
     * @param data 带解密的数据
     * @param privateKey 私钥
     * @return 解密后的数据
     * @throws Exception
     */
    public static String decrypt(String data, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(data));
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
}
